Expand description
RustCrypto: Ed25519
Edwards Digital Signature Algorithm (EdDSA) over Curve25519 as specified in RFC 8032.
About
This crate doesn’t contain an implementation of Ed25519, but instead
contains an ed25519::Signature
type which other crates can use in
conjunction with the signature::Signer
and signature::Verifier
traits.
These traits allow crates which produce and consume Ed25519 signatures to be written abstractly in such a way that different signer/verifier providers can be plugged in, enabling support for using different Ed25519 implementations, including HSMs or Cloud KMS services.
Minimum Supported Rust Version
This crate requires Rust 1.60 at a minimum.
Our policy is to allow MSRV to be raised in future released without that qualifing as a SemVer-breaking change, but it will be accompanied by a minor version bump, ensuring if you lock to a minor version MSRV will be preserved for the default feature set.
SemVer Policy
- All on-by-default features of this library are covered by SemVer
- MSRV is considered exempt from SemVer as noted above
- The
pkcs8
module is exempted as it uses a pre-1.0 dependency, however, breaking changes to this module will be accompanied by a minor version bump.
License
All crates licensed under either of
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Using Ed25519 generically over algorithm implementations/providers
By using the ed25519
crate, you can write code which signs and verifies
messages using the Ed25519 signature algorithm generically over any
supported Ed25519 implementation (see the next section for available
providers).
This allows consumers of your code to plug in whatever implementation they want to use without having to add all potential Ed25519 libraries you’d like to support as optional dependencies.
Example
use ed25519::signature::{Signer, Verifier};
pub struct HelloSigner<S>
where
S: Signer<ed25519::Signature>
{
pub signing_key: S
}
impl<S> HelloSigner<S>
where
S: Signer<ed25519::Signature>
{
pub fn sign(&self, person: &str) -> ed25519::Signature {
// NOTE: use `try_sign` if you'd like to be able to handle
// errors from external signing services/devices (e.g. HSM/KMS)
// <https://docs.rs/signature/latest/signature/trait.Signer.html#tymethod.try_sign>
self.signing_key.sign(format_message(person).as_bytes())
}
}
pub struct HelloVerifier<V> {
pub verifying_key: V
}
impl<V> HelloVerifier<V>
where
V: Verifier<ed25519::Signature>
{
pub fn verify(
&self,
person: &str,
signature: &ed25519::Signature
) -> Result<(), ed25519::Error> {
self.verifying_key.verify(format_message(person).as_bytes(), signature)
}
}
fn format_message(person: &str) -> String {
format!("Hello, {}!", person)
}
Using above example with ed25519-dalek
The ed25519-dalek
crate natively supports the ed25519::Signature
type defined in this crate along with the signature::Signer
and
signature::Verifier
traits.
Below is an example of how a hypothetical consumer of the code above can
instantiate and use the previously defined HelloSigner
and HelloVerifier
types with ed25519-dalek
as the signing/verification provider:
NOTE: requires ed25519-dalek
v2 or newer for compatibility with
ed25519
v2.2+.
use ed25519_dalek::{Signer, Verifier, Signature};
use rand_core::OsRng; // Requires the `std` feature of `rand_core`
/// `HelloSigner` defined above instantiated with `ed25519-dalek` as
/// the signing provider.
pub type DalekHelloSigner = HelloSigner<ed25519_dalek::SigningKey>;
let signing_key = ed25519_dalek::SigningKey::generate(&mut OsRng);
let signer = DalekHelloSigner { signing_key };
let person = "Joe"; // Message to sign
let signature = signer.sign(person);
/// `HelloVerifier` defined above instantiated with `ed25519-dalek`
/// as the signature verification provider.
pub type DalekHelloVerifier = HelloVerifier<ed25519_dalek::VerifyingKey>;
let verifying_key: ed25519_dalek::VerifyingKey = signer.signing_key.verifying_key();
let verifier = DalekHelloVerifier { verifying_key };
assert!(verifier.verify(person, &signature).is_ok());
Using above example with ring-compat
The ring-compat
crate provides wrappers for ring which implement
the signature::Signer
and signature::Verifier
traits for
ed25519::Signature
.
Below is an example of how a hypothetical consumer of the code above can
instantiate and use the previously defined HelloSigner
and HelloVerifier
types with ring-compat
as the signing/verification provider:
use ring_compat::signature::{
ed25519::{Signature, SigningKey, VerifyingKey},
Signer, Verifier
};
use rand_core::{OsRng, RngCore}; // Requires the `std` feature of `rand_core`
/// `HelloSigner` defined above instantiated with *ring* as
/// the signing provider.
pub type RingHelloSigner = HelloSigner<SigningKey>;
let mut ed25519_seed = [0u8; 32];
OsRng.fill_bytes(&mut ed25519_seed);
let signing_key = SigningKey::from_bytes(&ed25519_seed);
let verifying_key = signing_key.verifying_key();
let signer = RingHelloSigner { signing_key };
let person = "Joe"; // Message to sign
let signature = signer.sign(person);
/// `HelloVerifier` defined above instantiated with *ring*
/// as the signature verification provider.
pub type RingHelloVerifier = HelloVerifier<VerifyingKey>;
let verifier = RingHelloVerifier { verifying_key };
assert!(verifier.verify(person, &signature).is_ok());
Available Ed25519 providers
The following libraries support the types/traits from the ed25519
crate:
ed25519-dalek
- mature pure Rust implementation of Ed25519ring-compat
- compatibility wrapper for ringyubihsm
- host-side client library for YubiHSM2 devices from Yubico
Features
The following features are presently supported:
-
pkcs8
: support for decoding/encoding PKCS#8-formatted private keys using theKeypairBytes
type. -
std
(default): Enablestd
support insignature
, which currently only affects whethersignature::Error
implementsstd::error::Error
. -
serde
: Implementserde::Deserialize
andserde::Serialize
forSignature
. Signatures are serialized as their bytes. -
serde_bytes
: Implementserde_bytes::Deserialize
andserde_bytes::Serialize
forSignature
. This enables more compact representations for formats with an efficient byte array representation. As per theserde_bytes
documentation, this can most easily be realised using the#[serde(with = "serde_bytes")]
annotation, e.g.:ⓘ#[derive(Deserialize, Serialize)] #[serde(transparent)] struct SignatureAsBytes(#[serde(with = "serde_bytes")] Signature);
Re-exports
pub use crate::pkcs8::KeypairBytes;
pub use crate::pkcs8::PublicKeyBytes;
pub use signature;
Modules
- pkcs8
pkcs8
PKCS#8 private key support.
Structs
- Signature errors.
- Ed25519 signature.
Traits
- Support for decoding/encoding signatures as bytes.
Type Aliases
- Size of an
R
ors
component of an Ed25519 signature when serialized as bytes. - Ed25519 signature serialized as a byte array.